// 2013-8-1下午06:14:35  net.betou.trade.main.manager.impl.TradeMngImpl.java

package net.betou.trade.main.manager.impl;

import java.util.List;

import net.betou.common.hibernate3.Updater;
import net.betou.common.page.Pagination;
import net.betou.core.entity.ConfigLogin;
import net.betou.core.service.PostDataListener;
import net.betou.trade.entity.main.AgentAndAdmins;
import net.betou.trade.entity.main.Trade;
import net.betou.trade.entity.main.User;
import net.betou.trade.main.dao.TradeDao;
import net.betou.trade.main.manager.CategoryMng;
import net.betou.trade.main.manager.TradeMng;
import net.betou.trade.main.manager.UserMng;
import net.betou.trade.role.setting.CommonFinderConfig;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 
 * @author 叶装装
 */
@Service
@Transactional
public class TradeMngImpl implements TradeMng{

	public Trade deleteById( Integer id ) {
		return dao.deleteById( id );
	}

	public Trade [ ] deleteByIds( Integer [ ] ids ) {
		Trade [ ] beans = new Trade [ ids.length ];
		for ( int i = 0; i < ids.length; i++ ){
			beans[ i ] = dao.deleteById( ids[ i ] );
		}
		return beans;
	}
	
	@Transactional( readOnly = true )
	public Trade findById( Integer id ) {
		return dao.findById( id );
	}
	
	@Transactional( readOnly = true )
	public Trade findMyTrade( Integer id, Integer adminId, Boolean system ) {
		if( system ){
			return dao.findById( id );
		}
		return dao.findMyTrade( id, adminId );
	}
	
	@Transactional( readOnly = true )
	public Pagination getOpenTradePage( AgentAndAdmins admin, String searchProperty, String searchValue, String orderProperty, String orderDirection, int pageNo, int pageSize, String filterStatus ){
		if( admin.getSystem( ) ){
			return dao.getPage( true, null, searchProperty, searchValue, orderProperty, orderDirection, pageNo, pageSize, filterStatus );
		}
		
		CommonFinderConfig config = new CommonFinderConfig( admin, ConfigLogin.CONFIG_TRADE );
		if( config.isSelf( ) ){
			return dao.getPage( true, admin.getId( ), searchProperty, searchValue, orderProperty, orderDirection, pageNo, pageSize, filterStatus );
		}
		
		return dao.getPageByCriteria( searchProperty, searchValue, orderProperty, orderDirection, pageNo, pageSize, config.getDeepSQL( ) + " and status=1" );
	}
	
	@Transactional( readOnly = true )
	public Pagination getCloseTradePage( AgentAndAdmins admin, String searchProperty, String searchValue, String orderProperty, String orderDirection, int pageNo, int pageSize, String filterStatus ) {
		if( admin.getSystem( ) ){
			return dao.getPage( false, null, searchProperty, searchValue, orderProperty, orderDirection, pageNo, pageSize, filterStatus );
		}
		
		CommonFinderConfig config = new CommonFinderConfig( admin, ConfigLogin.CONFIG_CLOSE_TRADE );
		
		if( config.isSelf( ) ){
			return dao.getPage( false, admin.getId( ), searchProperty, searchValue, orderProperty, orderDirection, pageNo, pageSize, filterStatus );
		}
		
		return dao.getPageByCriteria( searchProperty, searchValue, orderProperty, orderDirection, pageNo, pageSize, config.getDeepSQL( ) + " and status=0" );
		
	}
	
	@Transactional( readOnly = true )
	public Pagination getPage( Boolean status,  User user,  int pageNo, int pageSize ){
		
		List< Integer > idList = userMng.getSearchId( user );
		if( idList.isEmpty( ) ){
			idList.add( user.getAdmin( ).getId( ) );
		}
		
		return dao.getPage( status, user.getGroup( ).getId( ), idList, pageNo, pageSize );
	}
	
	public Trade updateClose( Trade bean ){
		bean.initToCloseUpdate( );
		
		double profit;
		
		// 空单 建仓价 - 平仓价   多单  平仓价-建仓价
		
		if( bean.getDirection( ) ){ // 空单
			profit = bean.getOpenPosition( ) - bean.getClosePosition( );
		}else{ // 多单
			profit = bean.getClosePosition( ) - bean.getOpenPosition( );
		}
		
		bean.setProfit( profit ); // 设置盈利点位
		
		Updater< Trade > updater = new Updater< Trade >( bean );
		updater.exclude( "orientedGroup" ); // 面向用户
		updater.exclude( "category" );  // 品种
		updater.exclude( "admin" );    // 添加用户
		updater.exclude( "openReason" );  // 建仓理由
		updater.exclude( "status" ); // 状态不更新
		Trade newBean =  dao.updateByUpdater( updater );
		
		newBean.setSend( bean.getSend( ) );
		
		afterUpdateClose( newBean );
		
		return bean;
	}

	public Trade saveClose(  Trade bean ) {
		
		bean.initToCloseSave( );
		
		double profit;
		
		// 空单 建仓价 - 平仓价   多单  平仓价-建仓价
		
		if( bean.getDirection( ) ){ // 空单
			profit = bean.getOpenPosition( ) - bean.getClosePosition( );
		}else{ // 多单
			profit = bean.getClosePosition( ) - bean.getOpenPosition( );
		}
		
		bean.setProfit( profit ); // 设置盈利点位
		
		Updater< Trade > updater = new Updater< Trade >( bean );
		updater.exclude( "orientedGroup" ); // 面向用户
		updater.exclude( "startDate" ); // 开始时间
		updater.exclude( "category" );  // 品种
		updater.exclude( "admin" );    // 添加用户
		updater.exclude( "openReason" );  // 建仓理由
		bean = dao.updateByUpdater( updater );
		
		afterSaveClose( bean );
		
		return bean;
	}

	public Trade saveOpen( AgentAndAdmins admin, String categoryName, Trade bean, String orientedGroup, String smsGroup ) {
		
		bean.setOrientedGroup( orientedGroup );
		bean.setSmsGroups( smsGroup );
		
		bean.initToOpenSave( );
		
		bean.setCategory( mng.findByName( categoryName ) );
		bean.setAdmin( admin );
		
		bean = dao.save( bean );
		
		afterSaveOpen( bean );
	
		return bean;
	}

	public Trade updateOpen( String categoryName, Trade bean, String orientedGroup, String smsGroup ) {
		
		bean.setCategory( mng.findByName( categoryName ) );
		bean.setOrientedGroup( orientedGroup );
		bean.setSmsGroups( smsGroup );
		
		Updater< Trade > updater = new Updater< Trade >( bean );
		updater.exclude( "admin" ); // 不更新用户
		updater.exclude( "status" ); 
		
		Trade newBean = dao.updateByUpdater( updater );
		
		newBean.setSend( bean.getSend( ) );
		
		afterUpdateOpen( newBean );
		
		return bean;
	}
	
	private void afterSaveOpen( Trade bean ){
		for( PostDataListener< Trade > p : openList ){
			p.afterSave( bean );
		}
	}
	
	private void afterUpdateOpen( Trade bean ){
		for( PostDataListener< Trade > p : openList ){
			p.afterChange( bean, null );
		}
	}
	
	
	private void afterSaveClose( Trade bean ){
		for( PostDataListener< Trade > p : closeList ){
			p.afterSave( bean );
		}
	}
	
	private void afterUpdateClose( Trade bean ){
		for( PostDataListener< Trade > p : closeList ){
			p.afterChange( bean, null );
		}
	}
	
	private List< PostDataListener< Trade > > openList;
	private List< PostDataListener< Trade > > closeList;
	
	
	public void setOpenList( List< PostDataListener< Trade >> openList ) {
		this.openList = openList;
	}

	public void setCloseList( List< PostDataListener< Trade >> closeList ) {
		this.closeList = closeList;
	}

	@Autowired
	private TradeDao dao;
	
	@Autowired
	private CategoryMng mng;
	
	@Autowired
	private UserMng userMng;

}
